#include "player.h"
#include <QDebug>
#include <QTime>
#include "math.h"

Player::Player(qreal x, qreal y, ConnectionPlayer* pl) : MovingObject()
{
	connectionPlayer = pl;
	connect(connectionPlayer, SIGNAL(positionChanged()), this, SLOT(updateItemPosition()));
	connect(connectionPlayer, SIGNAL(gunFired(qreal,qreal,qreal)), this, SLOT(fireGun(qreal,qreal,qreal)));
    setPosition(QPointF(x,y));
    radius = 9;
    wsp_m = 180.0 / 3.14159265;;
    setUsesMouse(false);
    connectionPlayer->dirs.clear();
	setDeathTime(0);
    setZValue(3);
}

Player::~Player()
{
	delete gun;
}

void Player::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
                QWidget *widget) {
    Q_UNUSED(option);
    Q_UNUSED(widget);

    qreal r = radius;
    painter->drawEllipse(-r,-r,r*2,r*2);
    QLineF line(0,0,radius,0);
    line.setAngle(getAngle());
    r = r - 1;

    QPen pen;
    QBrush brush;
    //brush.setColor(Qt::red);
    brush.setColor(QColor(255,150,150));
    brush.setStyle(Qt::SolidPattern);
    pen.setColor(QColor(255,150,150));
    painter->setPen(pen);
    painter->setBrush(brush);
    QRectF rectangle(-r, -r, 2*r, 2*r);
    QPainterPath piePath;

    double arc = 0;
    int item = 0;
    if (gun != NULL) {
        int status = gun->getStatus();
        if (status == 0)
        {
            item = gun->getClip();
            if (item != 0)
            {
                arc = 360.0 * (double(item) / double(gun->getClipSize()) );
            }
        } else {
            item = gun->getReload();
            if (item != 0)
            {
                arc = 360.0 * (double(item) / double(gun->getReloadTime() ));
            }
        }

    }

    if (item > 0)
    {
        piePath.moveTo(0, 0);
        piePath.arcTo(-r, -r, 2*r, 2*r, 0.0, arc);
        piePath.closeSubpath();
        painter->drawPath(piePath);

    }
    pen.setColor(Qt::black);
    painter->setPen(pen);
    painter->drawLine(line);
}

QRectF Player::boundingRect() const
{
    return QRect(-radius,-radius,radius*2,radius*2);
}

QPainterPath Player::shape() const
{
    QPainterPath path;
    path.addEllipse(boundingRect());
    return path;
}

ConnectionPlayer* Player::getConnectionPlayer()
{
	return connectionPlayer;
}

void Player::setConnectionPlayer(ConnectionPlayer* cp)
{
	connectionPlayer = cp;

}

void Player::playerTimeTick()
{
	connectionPlayer->playerTimeTick();
}

bool Player::movePlayer()
{
	bool result = false;
	checkIsAlive();
	if (getIsAlive())
	{
		setIsShooting(gun->updateGun());

		if (getUsesMouse())
		{
			aimAtMouse();
		}
	}

	playerTimeTick();

	if (getIsAlive())
	{
		result = movePlayerBy(getVelocity());
	}

	return result;
}

void Player::checkIsAlive()
{
	if (getIsAlive())
	{
		if (!isVisible()) setIsAlive(true);
	} else
	{
		if (isVisible()) setIsAlive(false);
	}
}

bool Player::movePlayerBy(qreal dx, qreal dy)
{
    return connectionPlayer->movePlayerBy(dx,dy);
}

bool Player::movePlayerBy(QLineF vector)
{
    return movePlayerBy(vector.dx(), vector.dy());
}

bool Player::movePlayerBy(QPointF vector)
{
	return movePlayerBy(vector.x(), vector.y());
}

void Player::setPlayerAngle(qreal ang)
{
    connectionPlayer->setAngle(ang);
    gun->setGunAngle(ang);
}

void Player::changeXPos(qreal x)
{
    changePos(x, this->y());
}

void Player::changeYPos(qreal y)
{
    changePos(this->x(), y);
}

void Player::changePos(QPointF p)
{
    setPos(p);
    realPos = p;
}

void Player::changePos(qreal x, qreal y)
{
    changePos(QPointF(x,y));
}

qreal Player::getRadius()
{
    return radius+1;
}

void Player::updateKeys(int nr) {
    connectionPlayer->dirs.push_front(nr);
}

void Player::aimAtMouse()
{
    if (getUsesMouse())
    {
        double xd = mouse->x() - realPos.rx();
        double yd = mouse->y() - realPos.ry() ;

        double add = 0.0;
        if (xd < 0) add = 180.0;
        double angle = wsp_m*atan(yd/xd) + add;

        setAngle(-angle);
    }
}

int Player::keyToNr(int key) {

        if (key==Qt::Key_A) {
                return 4;
        } else if (key==Qt::Key_W) {
                return 1;
        } else if (key==Qt::Key_D) {
                return 2;
        } else if (key==Qt::Key_S) {
                return 3;
        } else {
                return 0;
        }
}

void Player::keyPressEvent(QKeyEvent* evt) {
        if (!evt->isAutoRepeat()) {
                int nr = keyToNr(evt->key());
                if (nr != 0) {
                        updateKeys(nr);
                }
        }
}

void Player::keyReleaseEvent(QKeyEvent* evt) {
        if (!evt->isAutoRepeat()) {

                int nr = keyToNr(evt->key());
                if (nr != 0) {
                        connectionPlayer->dirs.removeOne(nr);
                }
        }
}

void Player::setMouse(Mouse* m)
{
    mouse = m;
    setUsesMouse(true);
    connect(mouse, SIGNAL(mousePressed(QMouseEvent*)), this, SLOT(onMousePressed(QMouseEvent*)));
    connect(mouse, SIGNAL(mouseReleased(QMouseEvent*)), this, SLOT(onMouseReleased(QMouseEvent*)));
}

void Player::setGun(Gun* g)
{
    gun = g;
    gun->setOwner(this);
    gun->fireReleased();
    setAngle(0);
    connect(gun, SIGNAL(gunFired(Bullet*)), this, SLOT(onGunFired(Bullet*)));
    connect(gun, SIGNAL(hitPlayer(Player*,Player*)), this, SLOT(onHitPlayer(Player*,Player*)));
}

Gun* Player::getGun()
{
	return gun;
}

void Player::setIsAlive(bool ia)
{
	//qDebug() << "making player alive" << ia;
	/*if (getIsAlive() != ia)
	{*/
		setVisible(ia);
		connectionPlayer->setIsAlive(ia);
		if (ia) {
			qDebug() << "I am alive" << isVisible();
			gun->resetGun();
			setHealth(100);
		}
		if (ia && !getIsRemote()) {
			grabKeyboard();
			//setPosition(connectionPlayer->getPos());
		}
	//}
}

void Player::setPosition(QPointF p)
{
	connectionPlayer->setPosition(p);
}

void Player::updateItemPosition()
{
	changePos(getPos());
	emit positionChanged(this);
}

void Player::setIsReloading(bool isr)
{
	if (isr && (gun->getStatus() == 0))
	{
		gun->startReloading();
	}
	else
	{
		gun->finishReloading();
	}
}

void Player::setIsShooting(bool iss)
{
	connectionPlayer->setIsShooting(iss);
}

void Player::setAngle(qreal a)
{
	connectionPlayer->setAngle(a);
	gun->setGunAngle(a);
}

void Player::setDirs(quint8 d1, quint8 d2)
{
	connectionPlayer->setDirs(d1,d2);
}

void Player::setIsRemote(bool isr)
{
	connectionPlayer->setIsRemote(isr);
}

void Player::decreaseHealth(qreal h)
{
	connectionPlayer->decreaseHealth(h);
}

void Player::unsetMouse()
{
    mouse = NULL;
    setUsesMouse(false);
}

QVector<Bullet*> Player::getBullets()
{
    return gun->getBullets();
}

quint32 Player::getDeathTime()
{
	return connectionPlayer->getDeathTime();
}

QPointF Player::getVelocity()
{
	return connectionPlayer->getVelocity();
}

void Player::setDeathTime(quint32 dt)
{
	connectionPlayer->setDeathTime(dt);
}

void Player::onMousePressed(QMouseEvent *evt)
{
	if (getIsAlive()) {
		gun->firePressed();
	}
}

void Player::onMouseReleased(QMouseEvent *evt)
{
	if (getIsAlive()) {
		gun->fireReleased();
	}
}

void Player::onHitPlayer(Player* p1, Player* p2)
{
	emit hitPlayer(p1,p2);
}

void Player::onGunFired(Bullet* b)
{
    if (b != NULL)
    {
        map()->addItem(b);
    }
}


void Player::fireGun(qreal x, qreal y, qreal angle)
{
	if (getIsAlive()) {
		if (getIsRemote())
		{
			gun->makeShootingPossible();
		}
		gun->fire(x,y,angle);
	}
}

void Player::fireGun()
{
	fireGun(getPos().x(), getPos().y(), getAngle());
}

Map *Player::map()
{
    return static_cast<Map *>(scene());
}

void Player::setNick(QString n)
{
	return connectionPlayer->setNick(n);
}
void Player::setScore(quint16 n)
{
	return connectionPlayer->setScore(n);
}
void Player::setPlayerId(quint8 n)
{
	return connectionPlayer->setPlayerId(n);
}
void Player::setHealth(qreal h)
{
	return connectionPlayer->setHealth(h);
}
void Player::setUsesMouse(bool um)
{
	return connectionPlayer->setUsesMouse(um);
}

QString Player::getNick()
{
	return connectionPlayer->getNick();
}
quint16 Player::getScore()
{
	return connectionPlayer->getScore();
}
quint8 Player::getPlayerId()
{
	return connectionPlayer->getPlayerId();
}
QPointF Player::getPos()
{
	return connectionPlayer->getPos();
}
bool Player::getIsAlive()
{
	return connectionPlayer->getIsAlive();
}
bool Player::getIsReloading()
{
	return connectionPlayer->getIsReloading();
}
bool Player::getIsShooting()
{
	return connectionPlayer->getIsShooting();
}
qreal Player::getAngle()
{
	return connectionPlayer->getAngle();
}
qreal Player::getSpeed()
{
	return connectionPlayer->getSpeed();
}
qreal Player::getHealth()
{
	return connectionPlayer->getHealth();
}
bool Player::getUsesMouse()
{
	return connectionPlayer->getUsesMouse();
}
bool Player::getIsRemote()
{
	return connectionPlayer->getIsRemote();
}




